package com.uzhie.web.controller.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.uzhie.exception.MonitorException;
import com.uzhie.jt808.jt1078.entity.JT_1205_Catalog;
import com.uzhie.jt808.msg.entity.BitConverter;
import com.uzhie.util.ConstantKit.MEDIA;
import com.uzhie.util.ConstantKit.UPLOAD;
import com.uzhie.web.anno.Auth;
import com.uzhie.web.bean.PayloadBean;
import com.uzhie.web.controller.http.comm.CommController;
import com.uzhie.web.module.Catalog;
import com.uzhie.web.module.Video;
import com.uzhie.web.service.ConfigureService;
import com.uzhie.web.service.MonitoringService;
import com.uzhie.web.service.PlayBackService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * 流媒体视频相关控制
 * Created by lilongfei on 2018/7/24.
 */
@Controller
@RequestMapping(value = "monitor")
public class MonitorController extends CommController {

    @Autowired
    MonitoringService monitoringService;
    @Autowired
    PlayBackService playBackService;
    @Autowired
    ConfigureService configureService;


    /**
     * 下达监控指令
     *
     * @param body vehicleNumber  设备手机号
     *             channel 前端通道号
     *             stream  码流
     *             type    监控类型
     * @return
     */
    @Auth
    @ResponseBody
    @RequestMapping(value = "monitorOrder")
    public PayloadBean monitorOrder(@RequestBody(required = false) JSONObject body) {
        try {
            JSONObject properties = configureService.readProperties();
            JSONObject media = properties.getJSONObject(MEDIA.getName());
            //流媒体ip
            final String ip = media.getString(MEDIA.IP.N());
            //流媒体端口号
            final String tcpPort = media.getString(MEDIA.TCP.N());
            //播放器相应链接端口
            String tcpPortVideo = media.getString(MEDIA.VIDEO_TCP_LIVE.N());
            //流媒体udp端口
            final String udpPort = media.getString(MEDIA.UDP.N());
            final String vehicleNumber = body.getString("vehicleNumber");
            //车辆车牌号
            String number = body.getString("number");
            final Integer channel = body.getInteger("channel");
            final Integer stream = body.getInteger("stream");
            final Integer type = body.getInteger("type");
            monitoringService.startOrder(vehicleNumber, ip, tcpPort, udpPort, channel, stream, type);
            String url = "http://" + ip + ":" + tcpPortVideo + "/" + number + ".0." + channel + "." + "0.0";
            JSONObject obj = new JSONObject();
            obj.put("url", url);
            return buildResponse(obj);
        } catch (IOException | IllegalArgumentException | MonitorException e) {
            return buildResponse(null, setError(0, e.getMessage()));
        }
    }

    /**
     * 用户监控命令指令
     *
     * @param body vehicleNumber 设备手机号
     *             channel  前端通道号
     *             stream   码流
     *             control  控制类型
     *             order  关闭类型
     * @return
     */
    @Auth
    @ResponseBody
    @RequestMapping(value = "monitorControl")
    public PayloadBean monitorControl(@RequestBody(required = false) JSONObject body) {
        try {
            String vehicleNumber = body.getString("vehicleNumber");
            Integer channel = body.getInteger("channel");
            Integer stream = body.getInteger("stream");
            Integer order = body.getInteger("order");
            Integer control = body.getInteger("control");
            String message = monitoringService.controlOrder(vehicleNumber, channel, order, stream, control);
            return buildResponse(message);
        } catch (MonitorException | IllegalArgumentException e) {
            return buildResponse(null, e.getMessage());
        }
    }

    @Auth
    @ResponseBody
    @RequestMapping(value = "monitorControls")
    public PayloadBean monitorControls(@RequestBody(required = false) JSONObject body) {
        try {
            JSONArray array = JSON.parseArray(body.getJSONArray("list").toJSONString());
            List<String> messages = new ArrayList<>();
            for (int i = 0; i < array.size(); i++) {
                JSONObject obj = array.getJSONObject(i);
                String vehicleNumber = obj.getString("vehicleNumber");
                Integer channel = obj.getInteger("channel");
                Integer stream = obj.getInteger("stream");
                Integer order = obj.getInteger("order");
                Integer control = obj.getInteger("control");
                messages.add(monitoringService.controlOrder(vehicleNumber, channel, order, stream, control));
            }
            return buildResponse(null);
        } catch (MonitorException | IllegalArgumentException e) {
            return buildResponse(null, e.getMessage());
        }
    }


    /**
     * 通过用户id查询左侧目录结构
     *
     * @param body userId 用户id
     * @return
     */
    @Auth
    @ResponseBody
    @RequestMapping(value = "queryCatalog")
    public PayloadBean queryCatalog(@RequestBody(required = false) JSONObject body) {
        try {
            String userId = body.getString("userId");
            List<Catalog> result = monitoringService.queryListByUserId(userId);
            return buildResponse(result);
        } catch (MonitorException | IllegalArgumentException e) {
            return buildResponse(null, e.getMessage());
        }
    }


    /**
     * 获取远程终端目录结构
     *
     * @param body number 车辆终端的视频目录
     *             startTime 查询起始时间
     *             endTime 查询终止时间
     *             warns 警告标识
     *             channel 查询通道
     *             stream 码流类型
     *             type 资源类型
     *             eqType 设备存储类型
     * @return 远程资源目录, 该目录不分页
     */
    @Auth
    @ResponseBody
    @RequestMapping(value = "queryOriginCatalog")
    public PayloadBean queryOriginCatalog(@RequestBody(required = false) JSONObject body) {
        try {
            String vehicleNumber = body.getString("vehicleNumber");
            String startTime = body.getString("startTime");
            String endTime = body.getString("endTime");
            JSONArray warnObj = body.getJSONArray("warns");
            long warns = BitConverter.ToULongList(warnObj);
            Integer channel = body.getInteger("channel");
            Integer stream = body.getInteger("stream");
            Integer type = body.getInteger("type");
            Integer local = body.getInteger("local");
            //从终端获取的 List<JT_1205_Catalog>
            JSONArray result = playBackService.queryMediaCatalog(vehicleNumber, channel, startTime, endTime
                    , warns, type, stream, local);
            if (result != null) {
                List<JT_1205_Catalog> catalogs = JSONArray.parseArray(result.toJSONString(), JT_1205_Catalog.class);
                return buildResponse(catalogs);
            } else {
                List<String> list = new ArrayList<>();
                return buildResponse(list);
            }
        } catch (MonitorException | IllegalArgumentException e) {
            return buildResponse(null, e.getMessage());
        }
    }

    /**
     * 下发远程复播指令
     *
     * @param body number 车牌号
     * @return
     */
    @Auth
    @ResponseBody
    @RequestMapping(value = "sendPlayBackOrder")
    public PayloadBean sendPlayBackOrder(@RequestBody(required = false) JSONObject body) {
        try {
            JSONObject properties = configureService.readProperties();
            JSONObject media = properties.getJSONObject(MEDIA.getName());
            //流媒体ip
            String ip = media.getString(MEDIA.IP.N());
            //流媒体复播tcp端口
            String tcpPort = media.getString(MEDIA.TCP_REPLAY.N());
            //播放器相应链接端口
            String tcpPortVideo = media.getString(MEDIA.VIDEO_TCP_LIVE.N());
            //流媒体复播udp端口
            String udpPort = media.getString(MEDIA.UDP.N());
            String vehicleNumber = body.getString("vehicleNumber");
            String number = body.getString("number");
            Integer channel = body.getInteger("channel");
            Integer stream = body.getInteger("stream");
            Integer type = body.getInteger("type");
            Integer local = body.getInteger("local");
            Integer backType = body.getInteger("backType");
            Integer multiple = body.getInteger("multiple");
            String startTime = body.getString("startTime");
            String endTime = body.getString("endTime");
            playBackService.startPlayBackOrder(vehicleNumber, ip, tcpPort, udpPort, channel, stream, type, local, backType, multiple, startTime, endTime);
            JSONObject object = new JSONObject();
            String url = "http://" + ip + ":" + tcpPortVideo + "/" + number + ".0." + channel + ".0.0.1";
            object.put("url", url);
            object.put("message", "下发成功");
            return buildResponse(object);
        } catch (IOException | MonitorException | IllegalArgumentException e) {
            return buildResponse(null, e.getMessage());
        }
    }

    /**
     * 下发远程播放控制
     *
     * @param body vehicleNumber 车辆内置sim卡
     *             channel 逻辑通道号
     *             control 播放控制类型
     *             multiple 播放倍速
     *             time 拖拽播放时间
     * @return
     */
    @Auth
    @ResponseBody
    @RequestMapping(value = "sendPlayBackControl")
    public PayloadBean sendPlayBackControl(@RequestBody(required = false) JSONObject body) {
        try {
            playBackService.playBackControl(body.getString("vehicleNumber"), body.getInteger("channel"), body.getInteger("control"), body.getInteger("multiple"), body.getString("time"));
            return buildResponse(null);
        } catch (MonitorException | IllegalArgumentException e) {
            return buildResponse(null, e.getMessage());
        }
    }


    /**
     * 下发文件上传指令
     *
     * @param body vehicleNumber 车载终端的内置sim卡
     *             username ftp服务器用户名
     *             password ftp服务密码
     *             filePath ftp服务上传文件路径
     *             channel 逻辑通道号
     *             warns 报警标识
     *             type 视频文件类型
     *             stream 码流类型
     *             local 远程存储类型
     *             condition 上传条件
     *             startTime 上传起始时间
     *             endTime 上传截止时间
     * @return
     */
    @Auth
    @ResponseBody
    @RequestMapping(value = "upFile")
    public PayloadBean upFile(@RequestBody(required = false) JSONObject body) {
        try {
            JSONObject properties = configureService.readProperties();
            JSONObject upload = properties.getJSONObject(UPLOAD.getName());
            String ip = upload.getString(UPLOAD.URL.N());
            String port = upload.getString(UPLOAD.PORT.N());
            String username = upload.getString(UPLOAD.USER.N());
            String password = upload.getString(UPLOAD.PWD.N());
            String filePath = upload.getString(UPLOAD.MEDIA.N());
            playBackService.upFile(body.getString("vehicleNumber"), ip, port, username, password
                    , filePath, body.getInteger("channel"), body.getInteger("warns"), body.getInteger("type"), body.getInteger("stream")
                    , body.getInteger("local"), body.getInteger("condition"), body.getString("startTime"), body.getString("endTime"));
            return buildResponse(null);
        } catch (IOException | MonitorException | IllegalArgumentException e) {
            return buildResponse(null, e.getMessage());
        }
    }

    /**
     * 文件上传控制
     *
     * @param body
     * @return
     */
    @Auth
    @ResponseBody
    @RequestMapping(value = "upFileControl")
    public PayloadBean upFileControl(@RequestBody(required = false) JSONObject body) {
        try {
            playBackService.upFileControl(body.getString("vehicleNumber"), body.getInteger("number"), body.getInteger("control"));
            return buildResponse(null);
        } catch (MonitorException | IllegalArgumentException e) {
            return buildResponse(null, e.getMessage());
        }
    }


    /**
     * 查询流媒体服务器本地视频目录信息
     *
     * @param body vehicleNumber 车载终端sim卡
     *             channel 逻辑通道号
     *             startTime 起始时间 格式:yyyy-MM-dd HH:mm:ss
     *             endTime 截止时间 格式:yyyy-MM-dd HH:mm:ss
     *             warns 报警标识
     * @return
     */
    @Auth
    @ResponseBody
    @RequestMapping(value = "queryVideoList")
    public PayloadBean queryVideoList(@RequestBody(required = false) JSONObject body) {
        try {
            JSONObject properties = configureService.readProperties();
            JSONObject media = properties.getJSONObject(MEDIA.getName());
            //流媒体ip
            String ip = media.getString(MEDIA.IP.N());
            //nginx文件下载端口
            String tcpDownPort = media.getString(MEDIA.VIDEO_DOWN.N());
            //流媒体复播tcp端口
            String tcpReplayPort = media.getString(MEDIA.VIDEO_TCP_REPLAY.N());
            //播放器相应链接端口
            String vehicleNumber = body.getString("vehicleNumber");
            Integer channel = body.getInteger("channel");
            JSONArray warnObj = body.getJSONArray("warns");
            long warns = BitConverter.ToULongList(warnObj);
            List<Video> result = playBackService.queryVideoList(body.getString("vehicleNumber"), body.getInteger("channel"), body.getString("startTime"), body.getString("endTime"), warns + "");
            JSONObject object = new JSONObject();
            String url = "http://" + ip + ":" + tcpReplayPort + "/" + vehicleNumber + ".0." + channel + ".2.0.0.";
            String dowloadUrl = "http://" + ip + ":" + tcpDownPort;
            object.put("url", url);
            object.put("videoList", result);
            object.put("message", "下发成功");
            object.put("dowloadUrl", dowloadUrl);
            return buildResponse(object);
        } catch (MonitorException | IllegalArgumentException | IOException e) {
            return buildResponse(null, e.getMessage());
        }
    }

    /**
     * 保持心跳连接
     *
     * @param body
     * @return
     */
    @Auth
    @ResponseBody
    @RequestMapping(value = "keepPlayerLive")
    public PayloadBean keepPlayerLive(@RequestBody(required = false) JSONObject body) {
        try {
            JSONArray array = body.getJSONArray("params");
            for (Object object : array) {
                JSONObject obj = (JSONObject) object;
                monitoringService.PlayerKeepLive(obj.getString("status"),
                        obj.getString("simNo"), obj.getInteger("channel"), obj.getInteger("playType"));
            }
            return buildResponse(null);
        } catch (Exception e) {
            return buildResponse(null, e.getMessage());
        }
    }

}
